// Agent default in project Jasim
{ include("common.asl") }
{ include("default.request.asl") }
{ include("default.failure_recovery_plan.asl") }

/* Initial beliefs and rules */

busy :- fulfilling(_) | checking_pending_tasks.

/* Plans */

+!hello: true 
	<-
	.my_name(N); 
	.send(jasim, achieve, welcome(N)).

// this goal is delegated from jasim when all agents have been introduced.
+!start: true <-
	!hello;
	request_goals. 

@restart
+!restart: true
	<-
	.abolish(delegating(_,_,_));
	.abolish(delegated(_,_,_));
	.abolish(fulfilling(_));
	.abolish(pending_task(_,_,_));
		
	remove_percepts(request(_));
	
	.my_name(N);
	.send(jasim, tell, ready(N)).
	
/* --- goal satisfaction plans --- */
+request(G): true 
	<-
	.my_name(N);
	.print(N, " request goal: ", G);
	!request(N, G).
	
+!fulfill(N, G): true
	<-
	+fulfilling(G);
	mark(satisfies(N, G), executing);
	.print(N, " is fulfilling goal [", G,"]").
		
+fulfilled(G)[source(percept)]:  fulfilling(G)
	<-
	-fulfilling(G);
	.my_name(N);
	.print(N, " accomplished goal [", G,"]");
	.broadcast(tell, fulfilled(G));
	mark(satisfies(N, G), accomplished);
	ra_add(fact, satisfied(G));
	!empty_pending_task.

+fulfilled(G)[source(percept)]: true
	<-
	-fulfilled(G)[source(percept)].

+fulfilling(G): mode(continuous)
	<-
	+fulfilled(G)[source(percept)].

//-begin EmptyPending Task

+!empty_pending_task: busy <- true.

@ept1[atomic]
+!empty_pending_task: pending_task(fulfill(N, G))
	<-
	+checking_pending_tasks;
	-pending_task(fulfill(N, G))[source(_)];
	!fulfill(N, G);
	-checking_pending_tasks.

@ept2[atomic]
+!empty_pending_task: pending_task(delegation(S, T, G))
	<-
	+checking_pending_tasks;
	-pending_task(delegation(S, T, G))[source(_)];
	.send(S, tell, delegated(S, T, G));
	!fulfill(T, G);
	-checking_pending_tasks.
	
+!empty_pending_task : .my_name(N) 
	<- 
	.print(N, " is idle").

//-end	

// Delegation plans

+delegating(N, T, G):  true 
	<- 
	.print("PASSING:", N, " is going to pass [", G, "] to [", T, "]");
	.send(T, tell, pending_task(delegation(N, T, G))).

+delegated(N, T, G): true
	<-	
	-delegating(N, T, G);
	.print("PASSED:", N, " passed goal [", G, "] to [", T, "]");
	mark(passes(N, T, G), accomplished). 
	
+pending_task(_): true
	<-
	!empty_pending_task.
	
+pending_task(_): true
	<-
	.count(pending_task(_), N);
	.print(N, " task(s) pending.").